/**
   Copyright 2011 Фроловский А. В.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
   
   This file is a part of MyStats project
 */

/**
 * Row is a data row (just like in charts)
 */

package foo.mystats.model;

import foo.mystats.db.DbOpenHelper;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class Row {
	private static final int NO_ID_YET = -1;

	private long id;
	private String name;
	private String description;
	private boolean isTimeNeeded;
	private DataType dataType;

	public DataType getDataType() {
		return dataType;
	}

	public void setDataType(DataType _dataType) {
		this.dataType = _dataType;
	}

	public long getId() {
		return id;
	}

	public void setId(long _id) {
		this.id = _id;
	}

	public String getName() {
		return name;
	}

	public void setName(String _name) {
		if (_name == null) {
			throw new IllegalArgumentException("Row name cannot be null");
		}

		_name = _name.trim();

		if (_name.equals("")) {
			throw new IllegalArgumentException("Row name cannot be empty");
		}

		this.name = _name;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String _description) {
		if (_description == null) {
			this.description = "";
		}

		this.description = _description;
	}

	public boolean isTimeNeeded() {
		return isTimeNeeded;
	}

	public void setTimeNeeded(boolean _isTimeNeeded) {
		this.isTimeNeeded = _isTimeNeeded;
	}

	public Row(String _name, String _description, boolean _isTimeNeeded, DataType _dataType) {
		setId(NO_ID_YET);
		setName(_name);
		setDescription(_description);
		setTimeNeeded(_isTimeNeeded);
		setDataType(_dataType);
	}

	public static long insertRow(Context context, Row row) {
		DbOpenHelper dbOpenHelper = new DbOpenHelper(context);
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();

		ContentValues cv = new ContentValues();
		cv.put("name", row.getName());
		cv.put("description", row.getDescription());
		cv.put("is_time_needed", Integer.valueOf(row.isTimeNeeded() ? 1 : 0));
		cv.put("data_type", row.getDataType().getType());

		long rowid = -1;
		try {
			// SQLiteConstraintException is catched on a higher level
			rowid = db.insertOrThrow("row", null, cv);
			row.setId(rowid);
		} finally {
			db.close();
		}

		return rowid;
	}

	public static Row getRowById(Context context, long rowid) {
		Row result = null;

		DbOpenHelper dbOpenHelper = new DbOpenHelper(context);
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();

		Cursor c = null;
		try {
			c = db.rawQuery(
					"select id, name, description, is_time_needed, data_type from row where id = ?",
					new String[] { Long.toString(rowid) });
			c.moveToFirst();

			long id = c.getLong(0);
			String name = c.getString(1);
			String description = c.getString(2);
			boolean isTimeNeeded = (c.getInt(3) != 0);
			DataType dataType = new DataType(c.getInt(4));

			result = new Row(name, description, isTimeNeeded, dataType);
			result.setId(id);
		} catch (Exception ex) {

		} finally {
			if (c != null) {
				c.close();
			}
			if (db != null) {
				db.close();
			}
		}

		return result;
	}

	public static void updateRow(Context context, Row row) {
		final String updateSQL = "update row set name = ?, description = ? where id = ?";

		if (row == null) {
			throw new IllegalArgumentException("Row cannot be null.");
		}

		if (row.getId() == -1) {
			throw new IllegalArgumentException("Row should have an ID");
		}

		DbOpenHelper dbOpenHelper = new DbOpenHelper(context);
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();

		// SQLiteConstraintException is catched on a higher level
		try {
			db.execSQL(
					updateSQL,
					new String[] { row.getName(), row.getDescription(), Long.toString(row.getId()) });
		} finally {
			db.close();
		}
	}

	public static boolean deleteRowById(Context context, long rowid) {
		boolean result = false;

		DbOpenHelper dbOpenHelper = new DbOpenHelper(context);
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();

		try {
			db.execSQL("delete from row where id = ?", new String[] { Long.toString(rowid) });
			result = true;
		} finally {
			db.close();
		}

		return result;
	}

	public static int getRowsCount(Context context) {
		int result = -1;

		DbOpenHelper dbOpenHelper = new DbOpenHelper(context);
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		Cursor c = null;

		try {
			c = db.rawQuery("select count(*) as cnt from row", null);
			c.moveToFirst();

			result = c.getInt(0);
		} finally {
			if (c != null) {
				c.close();
			}
			if (db != null) {
				db.close();
			}
		}

		return result;
	}

	public String toString() {
		return String.format(
				"{id: '%d', name: '%s', description: '%s', is_time_needed: '%b', data_type: '%d'}",
				getId(), getName(), getDescription(), isTimeNeeded(), getDataType().getType());
	}

	public boolean equalsTo(Row r) {
		return (getId() == r.getId()) && (getName().equals(r.getName()))
				&& (getDescription().equals(r.getDescription()))
				&& (isTimeNeeded() == r.isTimeNeeded)
				&& (getDataType().getType() == r.getDataType().getType());
	}
}
